package genome;

public class NumericalGrammar extends Grammar {
	
	public double eval(){
		return eval(0);
	}
	
	public double eval(int depth){
		checkPoint();
		int dec = g.genome[point];
		
		int nArg = 2;
		
		//System.out.println("Decision for EVAL at point "+point+" is "+dec%nArg);
		
		if(depth==mx_depth){
			dec = 1; //return terminal
		}
		
		switch(dec%nArg){
			case 0:
				point++;
				return fn(depth+1);
			
			case 1:
				point++;
				return T();
		}
		return 0.0;
	}
	
	public double fn(int depth){
	
		int nArg = 4;
		
		double x;
		double y;
		
		x = eval(depth);
		y = eval(depth);
		
		checkPoint();
		int dec = g.genome[point];
		//System.out.println("Decision for function at point "+point+" is "+dec%nArg);
		
		point++;
		
		switch(dec%nArg){
			
			case 0:
				return x+y;
				
			case 1:
				return x-y;
				
			case 2:
				return x*y;
			
			case 3:
				if(y==0){return 1.0;} else{
				return x/y;
				}
		}
		return 0.0;
	}

	public double T(){
		int nArg = 1;
		checkPoint();
		int dec = g.genome[point];
		//System.out.println("Decision for terminal at point "+point+" is "+dec%nArg);
		
		point++;
		switch(dec%nArg){
			case 0:
				return g.input[0];
			
			//case 1:
			//	point++;
			//	return g.input[1];
		}
		return 0.0;
	}

	public String evalS(){
		return evalS(0);
	}
	
	public String evalS(int depth){
		checkPoint();
		int dec = g.genome[point];
		
		if(depth==mx_depth){
			dec = 1;
		}
		
		int nArg = 2;
		
		point++;
		switch(dec%nArg){
			case 0:
				return fnS(depth+1);
			
			case 1:
				return TS();
		}
		return "";
	}
	
	public String fnS(int depth){
	
		int nArg = 4;
		
		String x;
		String y;
		
		x = evalS(depth);
		y = evalS(depth);
		
		checkPoint();
		int dec = g.genome[point];
		point++;
		switch(dec%nArg){
			case 0:
				return "["+x+"+"+y+"]";
			
			case 1:
				return "["+x+"-"+y+"]";
				
			case 2:
				return "["+x+"*"+y+"]";
				
			case 3:
				return "["+x+"/"+y+"]";
		}
		return "0.0";
	}
	
	public String TS(){
		int nArg = 1;
		checkPoint();
		switch(g.genome[point]%nArg){
			case 0:
				point++;
				return "x";
		}
		return "0.0";
	}
}
